//==================================================================
//  Copyright (C) 2006  Davide Pasca
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//==================================================================
//==
//==
//==
//==================================================================

#ifndef M5D_MODEL_H
#define M5D_MODEL_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "m5d_types.h"

//==================================================================
namespace M5D {

class Sequence;

//==================================================================
class Model
{
public:
	class CopyParams
	{
	public:
		bool		_copy_geometry;
		bool		_copy_geometry_idx_dlist;
		bool		_copy_geometry_vtx_dlist;
		bool		_copy_geometry_verts;
		bool		_copy_geometry_trigs;
		bool		_copy_geometry_create_vtx_dlist;
		bool		_copy_geometry_create_vtx_dlist_forcetypes[VType::N];

		CopyParams()
		{
			SetDefault();
		}

		void SetDefault();
	};

public:
	//--------------------------------------------------------------
	const static int	NAME_MAXLEN = 64;

	const static int	FLG_EXISTED_BEFORE_LOAD = 2;
	const static int	FLG_EXISTED_IS_SERIALIZED = 4;

	//--------------------------------------------------------------
	enum Type
	{
		TYPE_NULL,
		TYPE_ROOT,
		TYPE_MESH,
		TYPE_PNTSPRT,
		TYPE_CAMERA,
		TYPE_LIGHT,
	};
	//--------------------------------------------------------------


	//--------------------------------------------------------------
	char				_mod_name[ NAME_MAXLEN ];
	Type				_mod_type;
	bool				_mod_visible;
	u_int				_mod_flags;
	Model				*_mod_nextp;
	Model				*_mod_childp;
	Model				*_mod_parentp;

	PMath::Matrix44		_mod_local_m;	// user set
	PMath::Matrix44		_mod_global_m;	// calculated

	class Scene			*_mod_scenep;

	void				*_userdatap;

	std::vector<Sequence *>	_sequences;

	//--------------------------------------------------------------
	Model( Type type, class Scene	*scenep, const char *namep=NULL );
	virtual ~Model();

	void			SetName( const char *namep );
	const char		*GetName(){ return _mod_name; }

	void			SetBranchVisibility( bool onoff );
	bool			IsVisible() const { return _mod_visible; };

	Type		GetType() const { return _mod_type; };

	virtual	const PMath::Vector3 *GetBBoxMinPtr() const	{ return NULL; }
	virtual	const PMath::Vector3 *GetBBoxMaxPtr() const	{ return NULL; }

	void			GetBranchBBox( PMath::Vector3 &bbox_min, PMath::Vector3 &bbox_max );
	void			UnlinkFromTree();
	virtual void	UpdateGlobalTransform();
	void			AddChild( Model *new_nodep );
	Model			*GetParent()				{ return _mod_parentp;	}
	Model			*GetChildlist()				{ return _mod_childp;	}
	const PMath::Matrix44	&GetMatrix() const
					{
						return _mod_local_m;
					}
	void			SetMatrix( const PMath::Matrix44 &local_m )
					{
						_mod_local_m = local_m;
					}
	const PMath::Matrix44	&GetGlobalMatrix() const
					{
						return _mod_global_m;
					}

	Model			*FindByName( const char *namep );

private:
	void			getBranchBBox_sub( PMath::Vector3 &bbox_min, PMath::Vector3 &bbox_max );
};
typedef autodel<Model>	Model_SP;

};	// namespace M5D

#endif
